'use strict';
const path = require('path');
const resolve = (dir) => path.resolve(__dirname, dir);
// 是否为生产环境
const IS_PROD = ['production', 'prod'].includes(process.env.NODE_ENV);
// 清理测试代码插件
const TerserPlugin = require('terser-webpack-plugin')
// gzip压缩插件
const CompressionPlugin = require('compression-webpack-plugin');

const GzipExtensionsPattern = /\.(js|css|json|txt|html|ico|svg)(\?.*)?$/i;
const CDN = {
    // 排除打包的第三方库
    /*externals: {
        vue: 'Vue',
        vuex: 'Vuex',
        'vue-router': 'VueRouter',
        //'element-ui':'element-ui',
        axios: 'axios',
        tinymce:'tinymce'
    },
    css: [
        //vue-cli-plugin-element插件css重组功能会受到影响
        //"//unpkg.com/element-ui@2.13.2/lib/theme-chalk/index.css"
    ],
    js: [
        "//unpkg.com/vue@2.6.11/dist/vue.min.js",
        "//unpkg.com/vuex@3.1.2/dist/vuex.min.js",
        "//unpkg.com/vue-router@3.1.2/dist/vue-router.min.js",
        //"//unpkg.com/element-ui@2.13.2/lib/index.js",
        "//unpkg.com/axios@0.19.2/lib/index.js",
        "//unpkg.com/tinymce@5.4.1/tinymce.js"
    ],*/
};

module.exports = {
    //同步spring boot包输出路径
    outputDir: process.env.VUE_APP_COMPILE_OUTPUT || 'dist',//''target/classes',
    indexPath: 'index.html',
    assetsDir: 'assets',
    //history模式下应为‘./’;必须以‘/’结尾
    publicPath: '/',
    //是否在开发环境下通过 eslint-loader 在每次保存时 lint 代码
    lintOnSave: false,
    //是否使用包含运行时编译器的 Vue 构建版本
    runtimeCompiler: !IS_PROD,
    //生产环境的 source map
    productionSourceMap: !IS_PROD,
    //多核加速
    parallel: require('os').cpus().length > 1,
    /*pages: {
        app: {
            entry: 'src/main.js',
            template: 'public/index.html',
            filename: 'index.html',
            title: process.env.PRODUCT_NAME || 'SynergyCloud',
            chunks: ['chunk-vendors', 'chunk-common', 'index'],
            cdn: CDN
        }
    },*/
    devServer: {
        // 让浏览器 overlay 同时显示警告和错误
        overlay: {
            warnings: true,
            errors: true
        },
        port: process.env.VUE_APP_PORT||5035,
        //自动打开浏览器
        open: true,
        //使用代理可以解决跨域访问问题
        proxy: {
            '/': {
                // 目标域地址
                target: process.env.VUE_APP_BASE_API||'http://localhost:8080/',
                //代理 websocket
                ws: true,
                //重写路径
                // pathRewrite: {
                //     "^/api": "/"
                // },
                // 将标头的原点更改为目标URL(开启跨域)
                changeOrigin: true,
                // 如果是https接口，需要配置这个
                //secure: false,
            },
        },
        //mock xdr请求数据
        //before: require('./mocks')
        /*before(app){
            console.log('dsdfasdf')
            app.post('/oauth/token', (rep, res) => res.json(require('@/../mocks/security/response/token.json')));
        }*/
    },
    // 这个值是一个对象，则会通过 webpack-merge 合并到最终的配置中。
    configureWebpack: config => {
        // 忽略CND配置
        config.externals = CDN.externals;
        // 分割代码块 @see https://webpack.docschina.org/plugins/split-chunks-plugin/
        // 使用CDN后就不能用这个了
        config.optimization={
            //runtimeChunk:true,
            splitChunks: {
                chunks: "all",   // 共有3个值"initial"，"async"和"all"。配置后，代码分割优化仅选择初始块，按需块或所有块
                minSize: 30000,   // （默认值：30k）代码分割的最小值
                minChunks: 1,    // （默认值：1）在拆分之前共享模块的最小块数
                maxAsyncRequests: 10,   //（默认为5）按需加载时并行请求的最大数量
                maxInitialRequests: 10,  //（默认值为3）入口点的最大并行请求数
                automaticNameDelimiter: '~',  // （默认值为'~'）默认情况下，webpack将使用块的来源和名称生成名称，例如vendors~main.js
                name: true,
                cacheGroups: {
                    // TODO 不知道为何，按如下配置始终只输出3个chunk，其他的都合并到app.js,未达到预期
                    'fullcalendar': {
                        name: 'fullcalendar',
                        test: /[\\/]node_modules[\\/]@fullcalendar[\\/]/,
                        priority: -10 //优先级越高，则优先匹配
                    },
                    'element-ui': {
                        name: 'element-ui',
                        test: /[\\/]node_modules[\\/]element-ui[\\/]/,
                        priority: -10
                    },
                    'lodash': {
                        name: 'lodash',
                        test: /[\\/]node_modules[\\/]lodash[\\/]/,
                        priority: -10
                    },
                    'tinymce': {
                        name: 'tinymce',
                        test: /[\\/]node_modules[\\/]tinymce[\\/]/,
                        priority: -10
                    },
                    vendors: {
                        name: 'vendors',
                        //chunks: 'initial',
                        // 匹配需拆分chunk的目录
                        test: /[\\/]node_modules[\\/]/,
                        priority: -20 // 拆分优先级
                    },
                    default: {   //所有代码分割快都符合默认值，此时判断priority优先级
                        minChunks: 2,
                        priority: -25,
                        reuseExistingChunk: true   // 允许在模块完全匹配时重用现有的块，而不是创建新的块。
                    }
                }
            }
        }
        if (IS_PROD) {
            config.plugins.push(
                // 开启 gzip 压缩 需要 npm i -D compression-webpack-plugin
                new CompressionPlugin({
                    filename: '[path].gz[query]',
                    algorithm: 'gzip',
                    test: new RegExp(GzipExtensionsPattern),  //匹配文件名
                    threshold: 10240,  //对超过10k的数据压缩
                    minRatio: 0.8,
                    deleteOriginalAssets: false  //不删除源文件
                }))

            config.optimization.minimizer = [
                //清理console、debugger行
                new TerserPlugin({
                    terserOptions: {
                        compress: {
                            warnings: false,
                            drop_console: true,
                            drop_debugger: true,
                            //自定义的日志输出语句
                            pure_funcs: ['console.log']
                        }
                    }
                })
            ]
        }
    },

    chainWebpack: config => {
        //优化请求数
        // 移除 prefetch 插件
        config.plugins.delete('prefetch')
        // 移除 preload 插件
        config.plugins.delete('preload');
        config.module
            .rule('swf')
            .test(/\.swf$/)
            .use('url-loader')
            .loader('url-loader')
            .tap((options) => {
                return {
                    limit: 10000,
                };
            });
        // 如果使用多页面打包，使用vue inspect --plugins查看html是否在结果数组中
        config.plugin("html").tap(args => {
            // 修复 Lazy loading routes Error
            args[0].chunksSortMode = "none";
            //  支持index中使用htmlWebpackPlugin.options.cdn
            args[0].cdn = CDN;
            return args;
        });

        //修复热更新失效，支持symlinks映射
        config.resolve.symlinks(true);
        // 添加别名
        config.resolve.alias
            .set('@', resolve('src'))
            /*.set('@packages', resolve('packages'))
            .set('@assets', resolve('src/assets'))
            .set('@components', resolve('src/components'))
            .set('@router', resolve('src/router'))
            .set('@store', resolve('src/store'))*/
            .set('@views', resolve('src/views'))
        // 压缩图片 需要 npm i -D image-webpack-loader
        /*config.module.rule("images").use("image-webpack-loader").loader("image-webpack-loader").options({
            mozjpeg: {progressive: true, quality: 75},
            optipng: {enabled: false},
            pngquant: {quality: [0.75, 0.9], speed: 4},
            gifsicle: {interlaced: false},
            webp: {quality: 75}
        });*/
        if (IS_PROD) {
            // 压缩代码
            config.optimization.minimize(false);
        }
    },
    css: {
        // 是否使用css分离插件 ExtractTextPlugin 生产环境下是true,开发环境下是false
        //extract: !IS_PROD,
        // 为所有的 CSS 及其预处理文件开启 CSS Modules。 这个选项不会影响 `*.vue` 文件。
        requireModuleExtension: true,
        sourceMap: !IS_PROD,
        // 为预处理器的 loader 传递自定义选项。比如传递给sass-loader 时，使用 `{ sass: { ... } }`。
        // loaderOptions: {
        //     sass: {
        //         prependData: `@import "~@/assets/scss/element.scss";`,
        //     },
        // },
    },
    pluginOptions: {
        electronBuilder: {
            builderOptions: {
                "appId": "cn.htsyb.synergy",
                "productName": "SynergyCloud",//项目名，也是生成的安装文件名，即aDemo.exe
                "copyright": "HTSYB © 2019",//版权信息
                "directories": {
                    "output": "./dist"//输出文件路径
                },
                "win": {//win相关配置
                    "icon": "./public/favicon.ico",//图标，当前图标在根目录下，必须为256X256
                    "target": [
                        {
                            "target": "nsis",//利用nsis制作安装程序
                            "arch": [
                                "x64"//64位
                            ]
                        }
                    ]
                },
                "nsis": {
                    "oneClick": false, // 是否一键安装
                    "allowElevation": true, // 允许请求提升。 如果为false，则用户必须使用提升的权限重新启动安装程序。
                    "allowToChangeInstallationDirectory": true, // 允许修改安装目录
                    "installerIcon": "./public/favicon.ico",// 安装图标
                    "uninstallerIcon": "./public/favicon.ico",//卸载图标
                    "installerHeaderIcon": "./public/favicon.ico", // 安装时头部图标
                    "createDesktopShortcut": true, // 创建桌面图标
                    "createStartMenuShortcut": true,// 创建开始菜单图标
                    "shortcutName": "SynergyCloud", // 图标名称
                },
            }
        }
    }
}
